interface Res {
  villageId: string;
  orderId: string;
  orderTypeName: string;
  message: string;
}

interface SocketMsg {
  mobile: string;
  message: Array<Res>;
}

class WebSocketClass {
  url: string;
  msgCallback: (e: Res) => void;
  name: string;
  ws: any;
  status: any;
  reconnectTimeout: any = null;
  pingPong: string | undefined;
  pingInterval: any;
  pongInterval: any;
  /**
   * @description: 初始化实例属性，保存参数
   * @param {String} url ws的接口
   * @param {Function} msgCallback 服务器信息的回调传数据给函数
   * @param {String} name 可选值 用于区分ws，用于debugger
   */
  constructor(url: string, msgCallback?: (e: Res) => void, name?: string) {
    try {
      this.url = url;

      // @ts-ignore
      this.msgCallback = msgCallback;

      //@ts-ignore
      this.name = name;

      this.ws = null; // websocket对象

      this.status = null; // websocket是否关闭
    } catch (error) {}
  }
  /**
   * @description: 初始化 连接websocket或重连webSocket时调用
   * @param {*} 可选值 要传的数据
   */
  connect(data?: any) {
    this.ws = new WebSocket(this.url);

    this.ws.onopen = () => {
      this.status = 'open';
      this.heartCheck(); // 心跳监测，防止连接自动断开

      if (data !== undefined) {
        console.log(data, '第一次请求');

        return this.ws.send(data);
      }
    };
    // 监听服务器端返回的信息
    this.ws.onmessage = (e) => {
      if (e.data === 'pong') {
        // 心跳消息不必回传
        this.pingPong = 'pong'; // 服务器端返回pong,修改pingPong的状态
      } else {
        return this.msgCallback(e.data);
      }
    };
    // ws关闭回调
    this.ws.onclose = (e) => {
      this.closeHandle(e);
    };
    // ws出错回调
    this.ws.onerror = (e) => {
      this.closeHandle(e);
    };
  }
  heartCheck() {
    // 心跳机制的时间可以自己与后端约定
    this.pingPong = 'ping'; // ws的心跳机制状态值
    this.pingInterval = setInterval(() => {
      setTimeout(() => {
        if (this.ws.readyState === 1) {
          // 检查ws为链接状态 才可发送
          this.ws.send('ping'); // 客户端发送ping
        }
      }, 0);
    }, 4000);
    this.pongInterval = setInterval(() => {
      setTimeout(() => {
        if (this.pingPong === 'ping') {
          //
          // this.closeHandle('pingPong没有改变为pong'); // 没有返回pong 重启webSocket
        }
        // 重置为ping 若下一次 ping 发送失败 或者pong返回失败(pingPong不会改成pong)，将重启
        //
        this.pingPong = 'ping';
      }, 0);
    }, 30000);
  }

  sendHandle(data: string) {
    return this.ws.send(data);
  }
  closeHandle(_e = 'err') {
    if (this.status !== 'close') {
      if (this.pingInterval !== undefined && this.pongInterval !== undefined) {
        clearInterval(this.pingInterval);
        clearInterval(this.pongInterval);
      }
      if (this.reconnectTimeout) clearTimeout(this.reconnectTimeout);
      this.reconnectTimeout = setTimeout(() => {
        this.connect(); // 非正常关闭则重连
      }, 30000);
    } else {
    }
  }
  // 手动关闭WebSocket
  closeMyself() {
    this.status = 'close';
    return this.ws.close();
  }
}

export { Res, SocketMsg, WebSocketClass };
